package main

import (
	"context"
	"github.com/hashicorp/consul/api"
	pb "grpc-demo/out_pb"
	"log"
	"net"

	"github.com/gofrs/uuid"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

func main() {
	// 1. 初始化 consul 配置
	consulConfig := api.DefaultConfig()

	// 2. 创建 consul 对象
	consulClient, err := api.NewClient(consulConfig)
	if err != nil {
		log.Println("创建 consul 对象失败", err)
	}

	// 3. 告诉 consul, 即将注册的服务的配置信息
	registerService := api.AgentServiceRegistration{
		ID:      "my_consul_id",
		Name:    "MakiFirstService",
		Tags:    []string{"标签A", "标签B", "TagC"},
		Port:    7001,
		Address: "127.0.0.1",
		Check: &api.AgentServiceCheck{
			CheckID:  "my_check_id",
			TCP:      "127.0.0.1:7001",
			Timeout:  "5s",
			Interval: "5s",
		},
	}

	// 注册 grpc 服务到 consul 上
	err = consulClient.Agent().ServiceRegister(&registerService)
	if err != nil {
		log.Println("consul 启动失败", err)
		return
	}
	log.Println("consul 启动成功")

	// 1. 初始化 grpc 对象
	s := grpc.NewServer()

	// 2. 注册服务
	pb.RegisterUserCenterServer(s, &server{})
	pb.RegisterNoticeCenterServer(s, &nServer{})

	// 3. 创建监听器，指定 IP 跟 port
	listener, err := net.Listen("tcp", "127.0.0.1:7001")
	if err != nil {
		log.Println("监听出错： ", err)
		return
	}
	log.Println("设置监听成功")

	// 4. 启动服务
	if err := s.Serve(listener); err != nil {
		log.Println("启动 gRPC 失败：", err)
		return
	}
}

// 定义类
type server struct {
	userMap map[string]*pb.User
}

type nServer struct {
}

// Register 绑定类方法，实现接口
// 用户注册
func (s *server) Register(ctx context.Context, req *pb.RegisterRequest) (resp *pb.RegisterResponse, err error) {
	out, err := uuid.NewV4()
	if err != nil {
		return resp, status.Errorf(codes.Internal, "生成 uuid 时出错 ", err)
	}
	req.User.Id = out.String()

	if s.userMap == nil {
		s.userMap = make(map[string]*pb.User)
	}
	s.userMap[req.User.Id] = req.User

	resp = &pb.RegisterResponse{}
	resp.UserId = req.User.Id
	return
}

// Login 用户登录
func (s *server) Login(ctx context.Context, req *pb.LoginRequest) (resp *pb.LoginResponse, err error) {
	if s.userMap == nil {
		s.userMap = make(map[string]*pb.User)
	}

	resp = &pb.LoginResponse{}

	aUser, ok := s.userMap[req.UserId]
	if !ok {
		return resp, nil
	}

	resp.Username = aUser.Username
	resp.Email = aUser.Email
	return
}

// ToEmail 邮件通知
func (n nServer) ToEmail(ctx context.Context, request *pb.EmailRequest) (*pb.BaseResponse, error) {
	log.Println("向用户：" + request.Username + " 发送一封电子邮件。收件人为：" + request.Email + " ，邮件内容为：" + request.Content)

	return &pb.BaseResponse{Code: 0, Message: "发送邮件成功"}, nil
}

// ToSms 短信通知
func (n nServer) ToSms(ctx context.Context, request *pb.SmsRequest) (*pb.BaseResponse, error) {
	log.Println("向手机号码：" + request.Mobile + " 发送一条短信 ，短信内容为：" + request.Content)

	return &pb.BaseResponse{Code: 0, Message: "发送短信成功"}, nil
}
